package cn.zmlio.mybatisdbchecker.utils;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;

import java.io.*;

public class ZipUtils {

    public static File unzip(String zipFile, String destDir) throws IOException {
        File dir = new File(destDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        try (FileInputStream fis = new FileInputStream(zipFile); ZipArchiveInputStream zais = new ZipArchiveInputStream(fis)) {

            ZipArchiveEntry entry;
            while ((entry = zais.getNextEntry()) != null) {
                File target = new File(destDir, entry.getName());

                // 防止 zip slip 漏洞
                String canonicalDestDir = dir.getCanonicalPath();
                String canonicalTarget = target.getCanonicalPath();
                if (!canonicalTarget.startsWith(canonicalDestDir + File.separator)) {
                    throw new IOException("Entry is outside of target directory: " + entry.getName());
                }

                if (entry.isDirectory()) {
                    target.mkdirs();
                    continue;
                }

                // 确保父目录存在
                boolean mkdirs = target.getParentFile().mkdirs();

                // 写入文件
                try (FileOutputStream fos = new FileOutputStream(target); BufferedOutputStream bos = new BufferedOutputStream(fos)) {
                    byte[] buffer = new byte[8192];
                    int len;
                    while ((len = zais.read(buffer)) != -1) {
                        bos.write(buffer, 0, len);
                    }
                }
            }
        }
        return dir;
    }
}